#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_uart.h"
#include "usart.h"
#include "dma.h"
#include "bsp_uart.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "queue.h"
#include "string.h"

//float yaw;
#if HWT101_ON
	#define HWT101_LEN	1 // 数组长度
	uint8_t ucTemp; // 专门用于接收HWT101数据
	uint8_t RxBuff[256] = {0};
	uint32_t Rx_cnt = 0;
	float HWT101_BufferA[HWT101_LEN] = {0}; // 双缓冲区
	float HWT101_BufferB[HWT101_LEN] = {0};
	
	struct HWT101_Device hwt101 = {0, HWT101_BufferA, HWT101_BufferB}; // 存储陀螺仪数据
#endif
	
#if RK3588_ON
	extern osMessageQueueId_t RK3588MessageHandle; // 往Process_Task 传输数据
	RK3588_Message_t g_rk3588_message;
	#define RK3588_LEN	3
	uint16_t RK3588_BufferA[RK3588_LEN] = {0}; // 双缓冲区
	uint16_t RK3588_BufferB[RK3588_LEN] = {0};
	uint8_t RK3588_Data[8]; // 存储rk3588数据
	struct RK3588_Device rk3588 = {0, RK3588_BufferA, RK3588_BufferB}; // 存储解析数据
#endif
// 串口号
enum{
	U1,
	U2,
	U3,
	U6,
};
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;
extern UART_HandleTypeDef huart6;
static struct UART_Device *g_cur_uart1_dev;
static struct UART_Device *g_cur_uart2_dev;
static struct UART_Device *g_cur_uart3_dev;
static struct UART_Device *g_cur_uart6_dev;

struct UART_Data {
    UART_HandleTypeDef *handle;
    SemaphoreHandle_t xTxSem; //信号量
    QueueHandle_t xRxQueue;
    uint8_t rxdatas[UART_RX_QUEUE_LEN];
};

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    struct UART_Data *data;
    if (huart == &huart1)
    {
        data = g_cur_uart1_dev->priv_data;
        /* 释放信号量 */
        xSemaphoreGiveFromISR(data->xTxSem, NULL);
    }
		if (huart == &huart2)
    {
			#if !HWT101_ON
        data = g_cur_uart2_dev->priv_data;
        /* 释放信号量 */
        xSemaphoreGiveFromISR(data->xTxSem, NULL);
			#else
				hwt101.clear_ok = 1;
			#endif
    }
		if (huart == &huart3)
    {
        data = g_cur_uart3_dev->priv_data;
        /* 释放信号量 */
        xSemaphoreGiveFromISR(data->xTxSem, NULL);
    }
		if (huart == &huart6)
    {
        data = g_cur_uart6_dev->priv_data;
        /* 释放信号量 */
        xSemaphoreGiveFromISR(data->xTxSem, NULL);
    }
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) // 接收到一个byte中断
{
		#if HWT101_ON
		uint8_t ucSum;
		uint16_t check; // 检测正负
		if (huart == &huart2)
		{
			RxBuff[Rx_cnt++] = ucTemp;
			if (RxBuff[0] != 0x55)
			{
				Rx_cnt--;
				HAL_UART_Receive_IT(&huart2, &ucTemp, sizeof(ucTemp));
				return;
			}
			if(Rx_cnt >= 11)
			{
				ucSum = __CaliSum(RxBuff, 10);
				if(ucSum != RxBuff[10])
				{
					Rx_cnt--;
					memcpy(RxBuff, &RxBuff[1], Rx_cnt);
					HAL_UART_Receive_IT(&huart2, &ucTemp, sizeof(ucTemp));
					return;
				}
				check = ((short)RxBuff[7] << 8) | (short)RxBuff[6];
//				if (RxBuff[1] == 0x52) // 角速度
//				{
//					
//				}
				if (RxBuff[1] == 0x53) // 角度
				{
					float yaw = 0;
					if (check & 0x8000) 
						yaw = (check - 0xffff)/32768.0f*180.0f;
					else
						yaw = check/32768.0f*180.0f;
						// 写入缓冲区
					hwt101.activeBuffer[0] = yaw;
					// 缓冲区切换
					hwt101.activeBuffer = (hwt101.activeBuffer == HWT101_BufferA) ? HWT101_BufferB : HWT101_BufferA;
					hwt101.taskBuffer = (hwt101.taskBuffer == HWT101_BufferA) ? HWT101_BufferB : HWT101_BufferA;
					hwt101.Flag_UART_RX_OK = 1; // 数据OK
				}
				Rx_cnt = 0;
			}
			if(Rx_cnt == 256)Rx_cnt = 0;
			HAL_UART_Receive_IT(&huart2, &ucTemp, sizeof(ucTemp));
		}
		#endif
    struct UART_Data *data;
    int len = huart->RxXferSize - huart->RxXferCount;
    if (huart == &huart1)
    {
        data = g_cur_uart1_dev->priv_data;
        /* 写队列 */
        for (int i = 0; i < len; i++)
        {
            xQueueSendFromISR(data->xRxQueue, &data->rxdatas[i], NULL);
        }
        /* 再次启动数据的接收 */
        HAL_UARTEx_ReceiveToIdle_DMA(data->handle, data->rxdatas, huart->RxXferSize);
    }
		if (huart == &huart3)
    {
			data = g_cur_uart3_dev->priv_data;
			/* 写队列 */
			xQueueSendFromISR(data->xRxQueue, &data->rxdatas, NULL);
      /* 再次启动数据的接收 */
			HAL_UARTEx_ReceiveToIdle_DMA(data->handle, data->rxdatas, huart->RxXferSize);
    }
		if (huart == &huart6)
    {
			data = g_cur_uart6_dev->priv_data;
			/* 写队列 */
			xQueueSendFromISR(data->xRxQueue, &data->rxdatas, NULL);
      /* 再次启动数据的接收 */
			HAL_UARTEx_ReceiveToIdle_DMA(data->handle, data->rxdatas, huart->RxXferSize);
    }
}
extern volatile uint8_t Open_RK3588_Recv_Flag;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) // 空闲中断
{
    struct UART_Data *data;
    if (huart == &huart1)
    {
        data = g_cur_uart1_dev->priv_data;
        /* 写队列 */
        xQueueSendFromISR(data->xRxQueue, &data->rxdatas, NULL); // 接收到的数据都在数组里面
        /* 再次启动数据的接收 */
        HAL_UARTEx_ReceiveToIdle_DMA(&huart1, data->rxdatas, huart->RxXferSize);
				__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
    }
		#if !HWT101_ON
		if (huart == &huart2)
		{
			HAL_UART_Receive_IT(data->handle, &ucTemp, sizeof(ucTemp));
		}
		#endif
		if (huart == &huart3)
		{
			#if !RK3588_ON
				data = g_cur_uart3_dev->priv_data;
        /* 写队列 */
				xQueueSendFromISR(data->xRxQueue, (void*)data->rxdatas, NULL);
				HAL_UARTEx_ReceiveToIdle_DMA(&huart3, data->rxdatas, huart->RxXferSize);
			#else
				uint8_t sum = 0; // 校验和
				if (RK3588_Data[0] == 0x12 && RK3588_Data[7] == 0x5b)
				{
					sum += (RK3588_Data[2]<<8)|RK3588_Data[3];
					sum += (RK3588_Data[4]<<8)|RK3588_Data[5];
					if (sum == RK3588_Data[6])
					{
						uint16_t imgx = 0, imgy = 0;
						uint8_t kind;
						// 写缓冲区
						rk3588.activeBuffer[0] = kind;
						rk3588.activeBuffer[1] = imgx;
						rk3588.activeBuffer[2] = imgy;
						// 切换缓冲区
						rk3588.activeBuffer = (rk3588.activeBuffer == RK3588_BufferA) ? RK3588_BufferB : RK3588_BufferA;
						rk3588.taskBuffer = (rk3588.taskBuffer == RK3588_BufferA) ? RK3588_BufferB : RK3588_BufferA;
						rk3588.Flag_UART_RX_OK = 1; // 数据OK
						
						if (Open_RK3588_Recv_Flag)
						{
							g_rk3588_message.kind = rk3588.activeBuffer[0];
							g_rk3588_message.image_x = rk3588.activeBuffer[1];
							g_rk3588_message.image_y = rk3588.activeBuffer[2];
							/* 发送控制指令(立即) */
							if (osMessageQueuePut(RK3588MessageHandle, &g_rk3588_message, 0, 0) == osOK) {
												// 消息成功放入队列
							}
						}
					}
				}
        /* 再次启动数据的接收 */
				HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RK3588_Data, sizeof(RK3588_Data));
				__HAL_DMA_DISABLE_IT(&hdma_usart3_rx, DMA_IT_HT);
			#endif
		}
		if (huart == &huart6)
		{
				data = g_cur_uart6_dev->priv_data;
        /* 写队列 */
        xQueueSendFromISR(data->xRxQueue, &data->rxdatas, NULL);
        /* 再次启动数据的接收 */
				HAL_UARTEx_ReceiveToIdle_DMA(&huart6, data->rxdatas, huart->RxXferSize);
				__HAL_DMA_DISABLE_IT(&hdma_usart6_rx, DMA_IT_HT);
		}
}

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
	if (huart->ErrorCode & HAL_UART_ERROR_PE)
	{
		uint32_t temp = huart->Instance->SR;
		temp = huart->Instance->DR;
		huart->Instance->CR1 |= UART_IT_RXNE;
	}
	if (huart->ErrorCode & HAL_UART_ERROR_ORE)
	{
		uint32_t temp = huart->Instance->SR;
		temp = huart->Instance->DR;
		huart->Instance->CR1 |= UART_IT_RXNE;
	}
	if (huart->ErrorCode & HAL_UART_ERROR_FE)
	{
		uint32_t temp = huart->Instance->SR;
		temp = huart->Instance->DR;
		huart->Instance->CR1 |= UART_IT_RXNE;
	}
}

/******************************************************/
/* 使用DMA, FreeRTOS队列,信号量 */
/**
	* @brief	初始化串口相关变量 
  * @param  size 串口接收完成后向任务发送的队列大小
	* @retval	NULL
*/
static int stm32_dma_uart_init(struct UART_Device *pDev, int baud, int datas, char parity, int stop, uint8_t size)
{
    struct UART_Data *data = pDev->priv_data;
	
		switch(pDev->Uart_Num)
		{
			case U1:
				g_cur_uart1_dev = pDev;
				break;
			case U2:
				#if !HWT101_ON
					g_cur_uart2_dev = pDev;
					break;
				#endif
			case U3:
				#if !RK3588_ON
				g_cur_uart3_dev = pDev;
				break;
				#endif
			case U6:
				g_cur_uart6_dev = pDev;
				break;
			default:
				break;
		}
    data->xTxSem = xSemaphoreCreateBinary();
    data->xRxQueue = xQueueCreate(UART_RX_QUEUE_LEN, sizeof(uint8_t)*size);

    /* 启动第1次数据的接收 */
    HAL_UARTEx_ReceiveToIdle_DMA(data->handle, data->rxdatas, size);
    return 0;
}

static int stm32_dma_uart_send(struct UART_Device *pDev, uint8_t *datas, int len, int timeout_ms)
{
    struct UART_Data *data = pDev->priv_data;
    
    /* 仅仅是触发中断而已 */
    HAL_UART_Transmit_DMA(data->handle, datas, len);

    /* 等待发送完毕:等待信号量 */
    if (pdTRUE == xSemaphoreTake(data->xTxSem, timeout_ms))
        return 0;
    else
        return -1;
}

static int stm32_dma_uart_recv(struct UART_Device *pDev, uint8_t *data, int timeout_ms)
{
    struct UART_Data *uart_data = pDev->priv_data;
    
    /* 读取队列得到数据, 问题:谁写队列?中断:写队列 */
    if (pdPASS == xQueueReceive(uart_data->xRxQueue, data, timeout_ms))
        return 0;
    else
        return -1;
}

static struct UART_Data g_stm32_dma_uart1_data = {
    &huart1,
};
#if !HWT101_ON
static struct UART_Data g_stm32_dma_uart2_data = {
    &huart2,
};
#endif
#if !RK3588_ON
static struct UART_Data g_stm32_dma_uart3_data = {
    &huart3,
};
#endif
static struct UART_Data g_stm32_dma_uart6_data = {
    &huart6,
};

static struct UART_Device g_stm32_dma_uart1 = {
    "stm32_dma_uart1",
		U1,
    stm32_dma_uart_init,
    stm32_dma_uart_send,
    stm32_dma_uart_recv,
    &g_stm32_dma_uart1_data,
};
#if !HWT101_ON
static struct UART_Device g_stm32_dma_uart2 = {
    "stm32_dma_uart2",
		U2,
    stm32_dma_uart_init,
    stm32_dma_uart_send,
    stm32_dma_uart_recv,
    &g_stm32_dma_uart2_data,
};
#endif
#if !RK3588_ON
static struct UART_Device g_stm32_dma_uart3 = {
    "stm32_dma_uart3",
		U3,
    stm32_dma_uart_init,
    stm32_dma_uart_send,
    stm32_dma_uart_recv,
    &g_stm32_dma_uart3_data,
};
#endif
static struct UART_Device g_stm32_dma_uart6 = {
    "stm32_dma_uart6",
		U6,
    stm32_dma_uart_init,
    stm32_dma_uart_send,
    stm32_dma_uart_recv,
    &g_stm32_dma_uart6_data,
};
/******************************************************/
struct UART_Device *g_uart_devs[] = {
&g_stm32_dma_uart1, 
#if !HWT101_ON	
	&g_stm32_dma_uart2,
#endif
#if !RK3588_ON
	&g_stm32_dma_uart3,
#endif
	&g_stm32_dma_uart6,
};
struct UART_Device *GetUARTDevice(char *name)
{
    int i = 0;
    for (i = 0; i < sizeof(g_uart_devs)/sizeof(g_uart_devs[0]); i++)
    {
      if (0 == strcmp(name, g_uart_devs[i]->name))
				return g_uart_devs[i];
    }
    return NULL;
}
